package com.lance.answer.gui.answer.gk.answer.lms;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.lance.answer.gui.answer.AnswerObject;
import com.lance.answer.gui.answer.DealJsonString;
import com.lance.answer.gui.answer.Util;
import org.apache.commons.io.IOUtils;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.*;

/**
 * <p>学生点击所有的连接<p>
 * <p>
 * <p>
 * <p>
 * <p>
 * 工程经济,size:1
 *
 * @author : fengx
 * @since JDK8.0
 * create by fengx on 2021/7/15 14:47
 */
public class TestYiWangYi {


    public static final String JS = "var video = document.getElementsByTagName(\"video\");if(video.length>0){ video[0].src = \"https://jvod.300hu.com/vod/product/a7d50669-f57b-4da9-8cf8-43d04372cab0/0411e189a55b41cfada876041fa7fdd7.mp4?source=2&h265=h265/18799/d7d0ab77577f4ea0bcf5bc794316045a.mp4\";}";


    public static void main(String[] args) throws Exception {
        String driverPath = "d:\\ynouAutoStudy\\chromedriver.exe";
        ChromeDriver driver = Util.getDriver(driverPath);
        String url = "https://menhu.pt.ouchn.cn/site/ouchnPc/index";
        driver.get(url);
        Thread.sleep(3000);


        String userName = "1942001212871";
        String pwd = "Ouchn@2021";
        //  String subjectName = "习近平新时代中国特色社会主义思想";
        // String subjectName = "马克思主义基本原理概论";
        //    String subjectName = "中国近现代史纲要";
        String subjectName = "中国法制史";

        WebElement userNameInput = driver.findElement(By.id("loginName"));
        userNameInput.clear();
        userNameInput.sendKeys(userName);

        WebElement passwordInput = driver.findElement(By.id("password"));
        passwordInput.clear();
        passwordInput.sendKeys(pwd);
        //TimeUnit.SECONDS.sleep(1);

        // FIXME 要输入验证码
        Thread.sleep(10000);


        WebElement loginBtn = driver.findElement(By.name("button"));

        loginBtn.click();

        Thread.sleep(10000);


        // 在题库里获取答案
        Map<String, AnswerObject> answerMap = initAnswer(subjectName);

        // 进入课程首页
        for (WebElement we : driver.findElements(By.cssSelector("div[class='ouchnPc_index_course_div']"))) {
            String textContent = we.getText();
            System.err.println("text:" + textContent);
            if (textContent.contains(subjectName)) {
                we.findElement(By.tagName("a")).click();
                break;
            }
        }
        Util.switchToLast(driver);


        // TODO 现在开始获取具体课程所有的答题链接：：


        String cUrl = driver.getCurrentUrl();
        // 获取所有测验作业的页面
        driver.get(cUrl + "exam");
        Thread.sleep(5000);
        // 所有的作业信息页面的测验的个数
        int testingSize = driver.findElement(By.cssSelector("div[class='list-content clearfix ng-scope']"))
                .findElements(By.cssSelector("div[class='list-item row collapse ng-scope']")).size();

        boolean refresh = false;
        for (int i = 0; i < testingSize; i++) {
            // 单个测验信息
            if (refresh) {
                driver.get(cUrl + "exam");
                Thread.sleep(5000);
            }
            // fixme 需要确定这个测验的顺序 是否发生改变
            // FIXME 这里可以换一个解决思路  写一个while循环，每次都获取第一个未提交测验的作业，直到没有未提交的作业
            WebElement singleTestingInfo = driver.findElement(By.cssSelector("div[class='list-content clearfix ng-scope']"))
                    .findElements(By.cssSelector("div[class='list-item row collapse ng-scope']")).get(i);
            // shorten-title ng-binding

            try {
                // if(Integer.parseInt(singleTestingInfo.findElement(By.cssSelector("div[class='large-3 column']")).getText())>90){
                if (Integer.parseInt(singleTestingInfo.findElement(By.cssSelector("div[class='large-3 column']")).getText()) > 60) {
                    continue;
                }
            } catch (Exception e) {

            }
            refresh = true;
            singleTestingInfo.findElement(By.cssSelector("span[class='shorten-title ng-binding']")).click();
            Thread.sleep(10000);

            // TODO  开始答题
            System.err.println("开始答题啦..............");

            //  点击开始答题
            driver.findElement(By.cssSelector("div[class='exam-button-container ng-scope']")).findElement(By.tagName("span")).click();

            Thread.sleep(2000);

            //  for = confirm 点击勾选 我已知晓考试要求并承诺遵守考试纪律 ng-valid ng-touched ng-dirty ng-valid-parse ng-empty
            try {
                new WebDriverWait(driver, Duration.ofSeconds(20)).until((ExpectedCondition<WebElement>)
                        d -> Objects.requireNonNull(d).findElement(By.cssSelector("input[name='confirm']"))).click();
            } catch (Exception e) {

            }

            Thread.sleep(2000);

            // 确认开始答题
            for (WebElement startAnswerWe : new WebDriverWait(driver, Duration.ofSeconds(20)).until((ExpectedCondition<List<WebElement>>)
                    d -> Objects.requireNonNull(d).findElements(By.cssSelector("button[class='button button-green medium ng-binding']")))) {
                // button button-green medium ng-binding
                if ("开始答题".equals(startAnswerWe.getText()) || "继续答题".equals(startAnswerWe.getText())) {
                    startAnswerWe.click();
                    break;
                }

            }


            // 找到所有的问题element
            Thread.sleep(5000);
            List<WebElement> webElements = findWeElements(driver, "li[ng-class='subject.type']", 20);
            List<WebElement> questionElements = Lists.newLinkedList();

            webElements.forEach(e -> {
                if (!e.getAttribute("class").equals("subject ng-scope text")) {
                    questionElements.add(e);
                }
            });

            // 开始答题
            doAnswer(driver, questionElements, answerMap);


            // 提交答题并确认提交 button button-green ng-scope
            Thread.sleep(5000);

            // right ng-scope 可以判断答题进度来决定是否提交
            //  submitTesting(driver);
            Thread.sleep(5000);
            // TODO 正式环境放开  submitTesting(driver);

        }


        Thread.sleep(200000000);


        Thread.sleep(500000000);

//
    }

    private static Map<String,AnswerObject> initAnswer(String subjectName ) throws IOException {
        InputStream inputStream1 = new FileInputStream("D:\\project\\answer-tool\\src\\main\\resources\\" + subjectName + "\\" + subjectName + "-answer.json");
        String answerStr = IOUtils.toString(inputStream1, StandardCharsets.UTF_8);
        List<AnswerObject> list = JSONObject.parseArray(answerStr, AnswerObject.class);
        Map<String, AnswerObject> answerMap = Maps.newHashMap();
        for (AnswerObject answerObject : list) {
            answerMap.put(DealJsonString.delHTMLTag(Util.dealContent(answerObject.getQuestionTitle())), answerObject);
        }
        return answerMap;
    }

    private static void submitTesting(WebDriver driver) throws Exception {
        // 点击提交  交卷
        driver.findElement(By.cssSelector("a[class='button button-green ng-scope']")).click();

        // button button-green medium
        for (WebElement confirmBtn : findWeElements(driver, "button[class='button button-green medium']", 20)) {
            if ("确定".equals(confirmBtn.getText())) {
                confirmBtn.click();
                break;
            }
        }
    }


    private static void doAnswer(WebDriver driver, List<WebElement> questionWeList, Map<String, AnswerObject> answerMap) throws Exception {

        // fixme
        Thread.sleep(1000);
        // fixme

        System.err.println("questionWeListSize：" + questionWeList.size());


        for (WebElement questionWe : questionWeList) {
            WebElement summaryWe = questionWe.findElement(By.className("summary-title"));
            // fixme
            WebElement titleWe = summaryWe.findElement(By.cssSelector("p[class='ng-scope']"));
            String title = titleWe.getText();
            title = Util.dealContent(title);
            title = DealJsonString.delHTMLTag(title);
            AnswerObject answerObject = answerMap.get(title);
            if (answerObject == null) {
                System.err.println("答案不存在:" + title);
                // FIXME 如果问题不存在，就用HANLP来匹配
                double similarity = 0.0;
                String answerTitle = "";
                for (Map.Entry<String, AnswerObject> entry : answerMap.entrySet()) {
                    double k1 = DealJsonString.getSimilarity(title, entry.getKey());
                    if (k1 > similarity) {
                        similarity = k1;
                        answerTitle = entry.getKey();
                    }
                }
                System.err.println("answerTitle:" + answerTitle + " similarity:" + similarity);
                // 相似度为0.9 就选择
                if (similarity > 0.60) {
                    answerObject = answerMap.get(answerTitle);
                } else {
                    try {
                        Thread.sleep(20000000);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
            System.err.println("answerObject:" + JSONObject.toJSONString(answerObject));
            assert answerObject != null;
            String questionType = answerObject.getQuestionType();


            switch (questionType) {
                case "1":
                case "2":
                case "3": {
                    // 单选 多选 判断
                    doChoiceExercise(questionWe, answerObject.getAnswers());
                    break;
                }
                case "4": {
                    doGapFilling(questionWe, answerObject.getAnswers());
                    break;
                }
                case "5": {
                    doShortAnswer(questionWe, answerObject.getAnswers());
                    break;
                }
                case "6": {
//                    doGapFilling(driver, questionWe, answerObject.getAnswers(), ueditorIndexMap);
                    break;
                }
                default: {
                    throw new Exception("不支持的题型!" + questionType + answerObject.getQuestionTitle());
                }
            }
        }
    }

    private static void doShortAnswer(WebElement answerElement, List<String> realAnswers) throws UnsupportedEncodingException {

        //   answerElement.findElement(By.cssSelector("div[class='subject-body short-answer']")).sendKeys(realAnswers.get(0)); 不行
        answerElement.findElement(By.cssSelector("div[class='simditor-body needsclick']")).sendKeys(realAnswers.get(0));

    }

    private static void doGapFilling(WebElement answerElement, List<String> realAnswers) {
        try {
            StringBuilder sb = new StringBuilder();
            realAnswers.forEach(e -> sb.append(e).append(" "));
            answerElement.findElement(By.cssSelector("var[context='subject']")).clear();
            answerElement.findElement(By.cssSelector("var[context='subject']")).sendKeys(sb.toString());

        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    private static void doChoiceExercise(WebElement answerElement, List<String> realAnswers) {
        // 遍历题目的每一个选项
        for (WebElement singleAnswerElement : answerElement.findElements(By.cssSelector("li[class='option ng-scope vertical']"))) {


            String answerContent = singleAnswerElement.
                    findElement(By.cssSelector("div[class='option-content']")).getText();
            //兼容特殊字符
            answerContent = Util.dealContent(answerContent);
            System.err.println("answerContent:" + answerContent);
            // 找到单选框或复选框
            // el-checkbox el-radio
            //     WebElement labelElement = singleAnswerElement.findElement(By.cssSelector("label[ng-class='{'answered-option': option.id == subject.answeredOption}']"));
            WebElement labelElement = singleAnswerElement.findElement(By.tagName("label"));

            // 找到真正的点击按钮 el-radio__input el-checkbox__input
            WebElement realClickElement = singleAnswerElement.findElement(By.cssSelector("span[class='left']"));

            String labelClass = labelElement.getAttribute("class");
            System.err.println("labelClass:" + labelClass);

            WebElement clickWebElement = labelElement.findElement(By.tagName("input"));
            // FIXME 判断题0：对 1：错
            // 这里的ID是每个选项的ID answerContent是每个选项的内容
            for (String realAnswer : realAnswers) {
                System.err.println("origin:" + answerContent);
                // if (answerContent.equals(realAnswer)) {
                if (DealJsonString.delHTMLTag(answerContent).equals(DealJsonString.delHTMLTag(realAnswer))) {
                    System.err.println("realAnswer:" + realAnswer);
                    assert clickWebElement != null;
                    if (!clickWebElement.isSelected()) {
                        realClickElement.click();
                    }
                }
            }


        }
    }


    private static List<WebElement> findWeElements(WebDriver driver, String cssSelector, int second) {
        return (new WebDriverWait(driver, Duration.ofSeconds(second))).until((ExpectedCondition<List<WebElement>>)
                d -> {
                    assert d != null;
                    return d.findElements(By.cssSelector(cssSelector));
                });
    }


}
